#include "include/unilib.h"
#include "include/hvc.h"

#define UNILIB_FS_NUM 16

struct unilib_fs unilib_fs_list[UNILIB_FS_NUM];
u16 unilib_fs_num = 0;

bool unilib_fs_append(u64 cfg_user_addr) {
    u16 vm_id;
    struct unilib_fs_cfg cfg;
    if (copy_from_user(&cfg, (void *)cfg_user_addr,
                       sizeof(struct unilib_fs_cfg))) {
        WARNING("%s: copy from user failed", __func__);
        return false;
    }

    vm_id = cfg.vm_id;
    memcpy((void *)&unilib_fs_list[vm_id].cfg, (void *)&cfg,
           sizeof(struct unilib_fs_cfg));

    hvc_call(kva2ipa((u64)&unilib_fs_list[vm_id]), 0, 0, 0, 0, 0, 0,
             HVC_MODE(HVC_UNILIB, HVC_UNILIB_FS_APPEND));

    INFO(HVC_UNILIB
        "%s: VM [%d] fs name '%s',buf_va 0x%llx buf_ipa 0x%llx buf_pa 0x%llx\n",
        __func__, vm_id, unilib_fs_list[vm_id].cfg.name,
        unilib_fs_list[vm_id].cfg.buf_va, unilib_fs_list[vm_id].cfg.buf_ipa,
        unilib_fs_list[vm_id].cfg.buf_pa);

    if (copy_to_user((void *)cfg_user_addr, (void *)&unilib_fs_list[vm_id].cfg,
                     sizeof(struct unilib_fs_cfg))) {
        WARNING("%s: copy to user failed", __func__);
        return false;
    }

    unilib_fs_num++;

    INFO("%s: VM [%d] fs append success, fs_num %d\n", __func__, vm_id,
         unilib_fs_num);

    return true;
}

bool unilib_fs_finished(u64 arg) {
    int vm_id;
    u64 value;
    struct unilib_fs_ops_res res;
    if (copy_from_user(&res, (void *)arg, sizeof(struct unilib_fs_ops_res))) {
        WARNING("%s: failed to copy from user", __func__);
        return false;
    }
    vm_id = (int) res.flag;
    value = res.value;
    // INFO("%s: VM[%d] , ori flag %d, ori value %d, get ops res %lld\n", __func__,
    //      vm_id, (int) unilib_fs_list[vm_id].res.flag, (int) unilib_fs_list[vm_id].res.value,
    //      value);
    unilib_fs_list[vm_id].res.flag = vm_id;
    unilib_fs_list[vm_id].res.value = value;

    return true;
}
